function! plugin#vim_lsp#load() abort
    if !exists('g:lsp_loaded')
        packadd vim-lsp
        packadd vim-lsp-settings
    endif
    return exists('g:lsp_loaded')
endfunction

let g:lsp_auto_enable = 1
let g:lsp_use_native_client = 1
" Keep the focus in current window
let g:lsp_preview_keep_focus = 1
let g:lsp_preview_float = 1
let g:lsp_preview_autoclose = 1
let g:lsp_preview_doubletap = [function('lsp#ui#vim#output#focuspreview')]
let g:lsp_insert_text_enabled = 1
let g:lsp_text_edit_enabled = 1
let g:lsp_completion_documentation_enabled = 1
let g:lsp_completion_documentation_delay = 120
let g:lsp_diagnostics_enabled = 1
let g:lsp_diagnostics_echo_cursor = 1
let g:lsp_diagnostics_echo_delay = 500
let g:lsp_diagnostics_float_cursor = 1
let g:lsp_diagnostics_float_delay = 1000
let g:lsp_diagnostics_float_insert_mode_enabled = 1
let g:lsp_format_sync_timeout = -1
let g:lsp_diagnostics_highlights_enabled = 1
let g:lsp_diagnostics_highlights_insert_mode_enabled = 1
let g:lsp_diagnostics_highlights_delay = 200
let g:lsp_diagnostics_signs_enabled = 1
" let g:lsp_diagnostics_signs_error = {'text': '✗'}
" let g:lsp_diagnostics_signs_warning = {'text': '‼', 'icon': '/path/to/some/icon'} " icons require GUI
" let g:lsp_diagnostics_signs_hint = {'icon': '/path/to/some/other/icon'} " icons require GUI
let g:lsp_diagnostics_signs_insert_mode_enabled = 1
let g:lsp_diagnostics_signs_delay = 200
let g:lsp_diagnostics_signs_priority = 11
let g:lsp_diagnostics_signs_priority_map = {
            \ 'LspError': 11,
            \ 'LspWarning': 7,
            \ 'clangd_LspWarning': 11,
            \ 'clangd_LspInformation': 11
            \ }
let g:lsp_diagnostics_virtual_text_enabled = 1
let g:lsp_diagnostics_virtual_text_insert_mode_enabled = 1
let g:lsp_diagnostics_virtual_text_delay = 200
let g:lsp_diagnostics_virtual_text_prefix = "> "
let g:lsp_diagnostics_virtual_text_align = "right"
let g:lsp_diagnostics_virtual_text_padding_left = 2
" let g:lsp_diagnostics_virtual_text_wrap = "truncate"
let g:lsp_diagnostics_virtual_text_wrap = "wrap"
let g:lsp_document_code_action_signs_enabled = 1
" let g:lsp_document_code_action_signs_hint = {'text': 'A>'}
" let g:lsp_document_code_action_signs_hint = {'text': '‼', 'icon': '/path/to/some/icon'} " icons require GUI
" let g:lsp_document_code_action_signs_hint = {'icon': '/path/to/some/other/icon'} " icons require GUI
let g:lsp_document_code_action_signs_delay = 200
let g:lsp_inlay_hints_enabled = 1
let g:lsp_inlay_hints_delay = 200
let g:lsp_inlay_hints_mode = {
            \  'normal': ['curline'],
            \}
" let g:lsp_tree_incoming_prefix = "← "
let g:lsp_tree_incoming_prefix = "⬅️  "
let g:lsp_use_event_queue = 1
let g:lsp_document_highlight_enabled = 1
let g:lsp_document_highlight_delay = 200
let g:lsp_get_supported_capabilities = [function('lsp#default_get_supported_capabilities')]
let g:lsp_document_symbol_detail = 1
let g:lsp_peek_alignment = "center"
let g:lsp_preview_max_width  = -1
let g:lsp_signature_help_enabled = 1
let g:lsp_show_workspace_edits = 1
let g:lsp_hover_ui = 'preview'

function! plugin#vim_lsp#init() abort
    if plugin#vim_lsp#load()
        let g:vim_lsp_keymap = get(g:, 'vim_lsp_keymap', { 'name': '+vim-lsp',
                    \   'h': {  'name'  : '+hierarchy',
                    \           'i'     : ['<plug>(lsp-call-hierarchy-incoming)'	, 'incoming'	], 
                    \           'o'     : ['<plug>(lsp-call-hierarchy-outgoing)'	, 'outgoing'	], 
                    \           't'     : ['<plug>(lsp-type-hierarchy)'	          	, 'type'		], 
                    \        }, 
                    \   'f': {  'name'  : '+float',
                    \           'c'     : ['<plug>(lsp-code-action-float)'	        , 'code-action'	], 
                    \           'h'     : ['<plug>(lsp-hover-float)'	            , 'hover'	], 
                    \        }, 
                    \   'c': {  'name'  : '+code',
                    \           'a'     : ['<plug>(lsp-code-action)'	            , 'action'	], 
                    \           'p'     : ['<plug>(lsp-code-action-preview)'	    , 'preview'	], 
                    \           'l'     : ['<plug>(lsp-code-lens)'	                , 'lens'	], 
                    \        }, 
                    \   'd': ['<plug>(lsp-declaration)'	                , 'declaration'	], 
                    \   'D': ['<plug>(lsp-definition)'	                , 'definition'	], 
                    \   'H': ['<plug>(lsp-hover)'	                    , ''	], 
                    \   'k': {  'name'  : '+peek',
                    \           'd'     : ['<plug>(lsp-peek-declaration)'	    , 'declaration'	    ], 
                    \           'D'     : ['<plug>(lsp-peek-definition)'	    , 'definition'    	], 
                    \           'i'     : ['<plug>(lsp-peek-implementation)'	, 'implementation'	], 
                    \           't'     : ['<plug>(lsp-peek-type-definition)'	, 'type-definition'	], 
                    \        }, 
                    \   'v': {  'name'  : '+preview',
                    \           'h'     : ['<plug>(lsp-hover-preview)'	        , 'hover'	            ], 
                    \           'c'     : ['<plug>(lsp-preview-close)'	        , 'close'	            ], 
                    \           'f'     : ['<plug>(lsp-preview-focus)'	        , 'focus'	            ], 
                    \        }, 
                    \   'n': {  'name'  : '+next',
                    \           'd'     : ['<plug>(lsp-next-diagnostic)'	    , 'diagnostic'	        ], 
                    \           'D'     : ['<plug>(lsp-next-diagnostic-nowrap)'	, 'diagnostic-nowrap'	], 
                    \           'e'     : ['<plug>(lsp-next-error)'	            , 'error'	            ], 
                    \           'E'     : ['<plug>(lsp-next-error-nowrap)'	    , 'error-nowrap'	    ], 
                    \           'r'     : ['<plug>(lsp-next-reference)'	        , 'reference'	        ], 
                    \           'w'     : ['<plug>(lsp-next-warning)'	        , 'warning'	            ], 
                    \           'W'     : ['<plug>(lsp-next-warning-nowrap)'	, 'warning-nowrap'	    ], 
                    \        }, 
                    \   'p': {  'name'  : '+previous',
                    \           'd'     : ['<plug>(lsp-previous-diagnostic)'	, 'diagnostic'				], 
                    \           'D'     : ['<plug>(lsp-previous-diagnostic-nowrap)'	, 'diagnostic-nowrap'	], 
                    \           'e'     : ['<plug>(lsp-previous-error)'	        , 'error'					], 
                    \           'E'     : ['<plug>(lsp-previous-error-nowrap)'	, 'error-nowrap'			], 
                    \           'r'     : ['<plug>(lsp-previous-reference)'	    , 'reference'				], 
                    \           'w'     : ['<plug>(lsp-previous-warning)'	    , 'warning'					], 
                    \           'W'     : ['<plug>(lsp-previous-warning-nowrap)', 'warning-nowrap'			], 
                    \        }, 
                    \   '?': {  'name'  : '+document',
                    \           's'     : ['<plug>(lsp-document-symbol)'	        , 'symbol'	        ], 
                    \           'S'     : ['<plug>(lsp-document-symbol-search)'	    , 'search'	        ], 
                    \           'D'     : ['<plug>(lsp-document-diagnostics)'	    , 'diagnostics'	    ], 
                    \           'f'     : ['<plug>(lsp-document-format)'		    , 'format'	        ], 
                    \           'F'     : ['<plug>(lsp-document-range-format)'	    , 'range-format'	], 
                    \           'u'     : ['<plug>(lsp-signature-help)'			    , 'signature-help'	], 
                    \        }, 
                    \   'r': ['<plug>(lsp-references)'	, ''	], 
                    \   'R': ['<plug>(lsp-rename)'	, ''	], 
                    \   'w': {  'name'  : '+workspace',
                    \           's'     : ['<plug>(lsp-workspace-symbol)'	        , 'symbol'	        ], 
                    \           'S'     : ['<plug>(lsp-workspace-symbol-search)'	, 'search'	        ], 
                    \        }, 
                    \   'i': ['<plug>(lsp-implementation)'	            , 'implementation'	            ], 
                    \   's': ['<plug>(lsp-status)'		                , 'status'		                ], 
                    \   't': ['<plug>(lsp-type-definition)'	            , 'type'		                ], 
                    \ })
        call which_key#register('<C-c>', "g:vim_lsp_keymap", 'n')
        nmap <C-c> :WhichKey '<C-c>'<cr>
        augroup lsp_install
            au!
            autocmd User lsp_buffer_enabled call s:on_lsp_buffer_enabled()
            autocmd! CompleteDone * if pumvisible() == 0 | pclose | endif
            " Close preview window with <C-c>
            autocmd User lsp_float_opened nmap <buffer> <silent> <C-c>
                        \ <Plug>(lsp-preview-close)
            autocmd User lsp_float_closed nunmap <buffer> <C-c>
            if (executable('pylsp'))
                autocmd User lsp_setup call lsp#register_server({
                            \ 'name': 'pylsp',
                            \ 'cmd': {server_info->['pylsp']},
                            \ 'allowlist': ['python']
                            \ })
            endif
        augroup END
    endif
endfunction

function! s:on_lsp_buffer_enabled() abort
    setlocal omnifunc=lsp#complete
    setlocal signcolumn=yes
    nmap <buffer> gd <plug>(lsp-definition)
    nmap <buffer> <f2> <plug>(lsp-rename)
endfunction



